package com.software.sqlite.service.impl;

import com.software.sqlite.api.admin.v1.vo.AdminLoginUserVO;
import com.software.sqlite.common.BaseMapper;
import com.software.sqlite.entity.*;
import com.software.sqlite.mapper.TbMenuMapper;
import com.software.sqlite.mapper.TbRoleMapper;
import com.software.sqlite.mapper.TbRoleMenuMapper;
import com.software.sqlite.service.ITbRoleMenuService;
import com.software.sqlite.utils.CommonUtils;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;

import javax.annotation.Resource;
import java.util.*;

@Service
@Slf4j
public class TbRoleMenuService extends BaseService<TbRoleMenu,String,Object> implements ITbRoleMenuService {

    @Resource
    private TbRoleMenuMapper mapper;
    @Resource
    private TbRoleMapper roleMapper;
    @Resource
    private TbMenuMapper menuMapper;
    @Override
    protected BaseMapper<TbRoleMenu> getBaseMapper() {
        return mapper;
    }
    @Value("${file.basedir}")
    private String basedir;


    @Override
    public boolean batchSetMenu(String token, Long roleId,String roleName, String menuIds,String systemType,Integer sort) throws Exception {
        boolean result=false;
        AdminLoginUserVO loginUser=getLoginUser(token);
        TbRole role=roleMapper.selectByPrimaryKey(roleId);
        if(role!=null){
            role.setRoleName(roleName);
            role.setSystemType(systemType);
            role.setSort(sort);
            roleMapper.updateByPrimaryKey(role);
        }else{
            role=new TbRole();
            role.setRoleName(roleName);
            role.setSystemType(systemType);
            role.setSort(sort);
            role.setUseStatus("normal");
            role.setUpdateTime(new Date());
            role.setUpdateAdminId(loginUser.getUserId());
            role.setCreateTime(new Date());
            role.setCreateAdminId(loginUser.getUserId());
            roleMapper.insert(role);
            roleId=role.getRoleId();
        }
        String[] array=menuIds.split(",");
        if(array.length>0){
            List<TbRoleMenu> list=new ArrayList<>();
            for(String menuId:array){
                TbMenu menu=menuMapper.selectByPrimaryKey(CommonUtils.parseLongData(menuId));
                if(menu!=null){
                    TbRoleMenu roleMenu=new TbRoleMenu();
                    roleMenu.setMenuId(CommonUtils.parseLongData(menuId));
                    roleMenu.setRoleId(roleId);
                    roleMenu.setUseStatus("normal");
                    roleMenu.setCreateTime(new Date());
                    roleMenu.setCreateAdminId(loginUser.getUserId());
                    list.add(roleMenu);
                }
            }
            if(array.length==list.size()){
                mapper.deleteByRoleId(roleId);
                mapper.insertList(list);
            }
        }
        return result;
    }

    @Override
    public boolean edit(TbRoleMenu model) {
        boolean result=false;
        try{
            if(model!=null){
                AdminLoginUserVO loginUser=this.getLoginUser(model.getToken());
                model.setUseStatus("normal");
                if(model.getRoleId()==null){
                    model.setCreateTime(new Date());
                    model.setCreateAdminId(loginUser.getUserId());
                    add(model);
                }else{
                    model.setUpdateTime(new Date());
                    model.setUpdateAdminId(loginUser.getUserId());
                    model.setCreateTime(new Date());
                    model.setCreateAdminId(loginUser.getUserId());
                    update(model);
                }
                result=true;
            }
        }catch (Exception e){
            log.error(e.getMessage(),e);
        }
        return result;
    }

    @Override
    public void importData(TbRoleMenu model) throws Exception {
        log.info("importData...");
    }

    @Override
    public void exportData(TbRoleMenu model) throws Exception {
        log.info("exportData...");
    }

    @Override
    public  List<TbMenu> selectMenuListByRoleId(Long roleId){
        return mapper.selectMenuListByRoleId(roleId);
    }
    @Override
    public ParentTreeEntity getMenuTree(Long roleId) throws Exception {
        ParentTreeEntity parentTree=new ParentTreeEntity();
        List<TbMenu> menuList=selectMenuListByRoleId(roleId);
        Map<Long,Long> menuMap=new HashMap<>();
        if(menuList.size()>0){
            for(TbMenu item:menuList){
                if(item.getSpreadCount()>0)
                {
                    menuMap.put(item.getMenuId(),item.getMenuId());
                    if(menuMap.containsKey(item.getParentId()))
                    {
                        menuMap.remove(item.getParentId());
                    }
                }
            }
        }
        Long[] checkedArray=new Long[menuMap.size()];
        int index=0;
        if(menuMap.size()>0){
            for(Map.Entry entry:menuMap.entrySet()){
                checkedArray[index]=CommonUtils.parseLongData(entry.getKey());
                index++;
            }
        }
        List<TreeEntity> treeList=findChildren(menuList,-99L);
        parentTree.setTreeData(treeList);
        parentTree.setCheckedArray(checkedArray);
        return parentTree;
    }

    @Override
    public List<MenuInfo> getMenuInfo(Long roleId) throws Exception {
//        List<MenuInfo> allMenuInfo=new ArrayList<>();
//        MenuInfo system=new MenuInfo();
//        system.setTitle("后台管理");
//        system.setIcon("fa fa-address-book");
//        system.setTarget("");
//        system.setHref("_self");
//        List<TbMenu> menuList=selectMenuListByRoleId(roleId);
//        List<MenuInfo> menuInfoList=findMenuChildren(menuList,0L);
//        system.setChild(menuInfoList);
//        allMenuInfo.add(system);
//        return allMenuInfo;
        List<MenuInfo> allMenuInfo=new ArrayList<>();
        List<TbMenu> moduleMenuList=mapper.selectFirstMenuListByRoleId(roleId);
        if(moduleMenuList.size()>0)
        {
            for(TbMenu module:moduleMenuList)
            {
                MenuInfo system=new MenuInfo();
                system.setTitle(module.getTitle());
                system.setIcon(module.getIcon());
                system.setTarget(module.getTarget());
                system.setHref(module.getHref());
                List<TbMenu> menuList=selectMenuListByRoleId(roleId);
                List<MenuInfo> menuInfoList=findMenuChildren(menuList,module.getMenuId());
                system.setChild(menuInfoList);
                allMenuInfo.add(system);
            }
        }
        return allMenuInfo;
    }

    private List<MenuInfo> findMenuChildren(List<TbMenu> menuList, Long parentId)
    {
        List<MenuInfo> children=new ArrayList<>();
        if(menuList.size()>0){
            for(TbMenu _menu:menuList){
                if(parentId.equals( _menu.getParentId() ) && _menu.getSpreadCount()>0){
                    MenuInfo menu=new MenuInfo();
                    menu.setTitle(_menu.getTitle());
                    menu.setIcon(_menu.getIcon());
                    menu.setHref(_menu.getHref());
                    menu.setTarget(_menu.getTarget());
                    menu.setChild(findMenuChildren(menuList,_menu.getMenuId()));
                    children.add(menu);
                }
            }
        }
        return children;
    }

    private List<TreeEntity> findChildren(List<TbMenu> menuList, Long parentId)
    {
        List<TreeEntity> treeChildren=new ArrayList<>();
        if(menuList.size()>0){
            for(TbMenu menu:menuList){
                if(parentId.equals( menu.getParentId() )){
                    TreeEntity tree=new TreeEntity();
                    tree.setId(menu.getMenuId());
                    tree.setTitle(menu.getTitle());
                    tree.setSpread(menu.getSpreadCount()>0?true:false);
                    tree.setChildren(findChildren(menuList,menu.getMenuId()));
                    treeChildren.add(tree);
                }
            }
        }
        return treeChildren;
    }
}
